package com.qsl.file;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * @description:
 * @author: 青石路
 * @createDate: 2023/8/10 9:22
 **/
public class UnzipTest {

    public static void main(String[] args) throws IOException {
        // unzipFile("D:/download_unzip/", "企债指数(399481)_20230810_050054.xlsx.zip", "D:/download_unzip/");
        // unzipFile("D:/download_unzip/", "企债指数(399481)_20230810_080725.xlsx.zip", "D:/download_unzip/");
        // uncompress(new File("D:/download_unzip/企债指数(399481)_20230810_050054.xlsx.zip"), "D:/download_unzip");
        unzip(new File("D:/download_unzip/20230811/企债指数(399481)_20230811_080705.xlsx.zip"), "D:/download_unzip/20230811");
    }

    public static boolean unzipFile(String srcDir, String objFile, String destDir) throws IOException {
        try (
                FileInputStream fis = new FileInputStream(srcDir + File.separator + objFile);
                ZipInputStream zis = new ZipInputStream(fis);
                BufferedInputStream bis = new BufferedInputStream(zis)
        ) {
            ZipEntry zipEntry = zis.getNextEntry();
            while (zipEntry != null) {
                File newFile = createFile(destDir, zipEntry.getName());
                try (
                        FileOutputStream fos = new FileOutputStream(newFile);
                        BufferedOutputStream bos = new BufferedOutputStream(fos)
                ) {
                    int len;
                    while ((len = bis.read()) != -1) {
                        bos.write(len);
                    }
                    zipEntry = zis.getNextEntry();
                }
            }
            zis.closeEntry();
            return true;
        }
    }

    /**
     * 创建文件
     *
     * @param dir      目录名
     * @param fileName 文件名（包括后缀）
     * @return 文件（全路径）
     */
    public static File createFile(String dir, String fileName) throws IOException {
        File file = new File( dir + File.separator + fileName);
        if (!file.exists()) {
            boolean created = file.createNewFile();
            if (!created) {
                throw new RuntimeException("文件：" + file.getPath() + " 创建失败，它已存在");
            }
        }
        return file;
    }

    /**
     * commons.compress 解压
     * @param sourceFile
     * @param target
     * @throws IOException
     */
    public static void uncompress(File sourceFile, String target) throws IOException {
        try (ZipArchiveInputStream inputStream = new ZipArchiveInputStream(
                new BufferedInputStream(new FileInputStream(sourceFile)))) {
            ZipArchiveEntry zipArchiveEntry;

            while( (zipArchiveEntry = inputStream.getNextZipEntry()) != null) {
                try (BufferedOutputStream outputStream = new BufferedOutputStream(
                        new FileOutputStream(new File(target + "\\" + zipArchiveEntry.getName())))) {
                    byte[] buffer = new byte[1024];
                    int len;
                    while((len = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, len);
                    }
                }
            }
        }
    }

    public static File [] unzip(File zipFile, String dest) throws ZipException {
        ZipFile zFile = new ZipFile(zipFile);
        if (!zFile.isValidZipFile()) {
            throw new ZipException("压缩文件不合法,可能被损坏.");
        }
        File destDir = new File(dest);
        if (destDir.isDirectory() && !destDir.exists()) {
            destDir.mkdir();
        }
        zFile.extractAll(dest);

        List<FileHeader> headerList = zFile.getFileHeaders();
        List<File> extractedFileList = new ArrayList<>();
        for(FileHeader fileHeader : headerList) {
            if (!fileHeader.isDirectory()) {
                extractedFileList.add(new File(destDir,fileHeader.getFileName()));
            }
        }
        File [] extractedFiles = new File[extractedFileList.size()];
        extractedFileList.toArray(extractedFiles);
        return extractedFiles;
    }
}
